class_name Enemy
extends Area2D

const ARROW_OFFSET = 5

@export var stats: EnemyStats: set = _set_enemy_stats

@onready var sprite_2d: Sprite2D = %Sprite2D
@onready var arrow: Sprite2D = %Arrow
@onready var stats_ui: StatsUI = %StatsUI
@onready var intent_ui: IntentUI = %IntentUI
@onready var status_handler: StatusHandler = %StatusHandler
@onready var modifier_handler: ModifierHandler = %ModifierHandler

var enemy_action_picker: EnemyActionPicker
var current_action: EnemyAction: set = _set_current_action

func _set_current_action(value: EnemyAction) -> void:
	current_action = value
	update_intent()
	

func update_intent() -> void:
	if current_action:
		current_action.update_intent_text()
		intent_ui.update_intent(current_action.intent)

func _set_enemy_stats(value: EnemyStats) -> void:
	stats = value.create_instance()
	if not stats.stats_changed.is_connected(update_stats):
		stats.stats_changed.connect(update_stats)
		stats.stats_changed.connect(update_action)
	update_enemy()
	
func update_action() -> void:
	if not enemy_action_picker:
		return
	if not current_action:
		current_action = enemy_action_picker.get_action()
		return
	var new_conditional_action := enemy_action_picker.get_first_conditional_action()
	if new_conditional_action and new_conditional_action != current_action:
		current_action = new_conditional_action
	
func setup_ai() -> void:
	if enemy_action_picker:
		enemy_action_picker.queue_free()
	enemy_action_picker = stats.ai.instantiate()
	add_child(enemy_action_picker)
	enemy_action_picker.enemy = self
	
func update_enemy() -> void:
	if not stats is Stats:
		return
	if not is_inside_tree():
		await ready
	sprite_2d.texture = stats.art
	arrow.position = Vector2.RIGHT * (sprite_2d.get_rect().size.x / 2 + ARROW_OFFSET)
	setup_ai()
	update_stats()
	
func do_turn() -> void:
	stats.block = 0
	if not current_action:
		return
	current_action.perform_action()

func update_stats() -> void:
	stats_ui.update_stats(stats)
	
func take_damage(value: int, which_modifier: Modifier.Type) -> void:
	if stats.health <= 0:
		return
	var modifier_value := modifier_handler.get_modified_value(value, which_modifier)
	sprite_2d.material = AutoLoader.WHITE_SPRITE_MATERIAL
	var tween := create_tween()
	tween.tween_callback(Shaker.shake.bind(self, 16, 0.15))
	tween.tween_callback(stats.take_damage.bind(modifier_value))
	tween.tween_interval(0.17)
	tween.finished.connect(func():
		sprite_2d.material = null
		if stats.health <= 0:
			Events.do_enemy_died(self)
			queue_free()
	)


func _on_area_entered(_area: Area2D) -> void:
	arrow.show()


func _on_area_exited(_area: Area2D) -> void:
	arrow.hide()
